package com.itheima.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.itheima.autoconfig.template.HuanXinTemplate;
import com.itheima.autoconfig.template.SmsTemplate;
import com.itheima.commons.utils.Constants;
import com.itheima.commons.utils.JwtUtils;
import com.itheima.dubbo.api.*;
import com.itheima.model.domain.Activity;
import com.itheima.model.domain.User;
import com.itheima.model.domain.UserInfo;
import com.itheima.model.enums.LogTypeEnum;
import com.itheima.model.mongo.UserLike;
import com.itheima.model.mongo.Visitors;
import com.itheima.model.vo.ErrorResult;
import com.itheima.model.vo.FriendsVo;
import com.itheima.model.vo.PageResult;
import com.itheima.server.exception.BusinessException;
import com.itheima.server.interceptor.UserHolder;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.tomcat.util.bcel.Const;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.*;


@Service
public class UserService {

    @Autowired
    private SmsTemplate template;
    @DubboReference
    private UserApi userApi;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @DubboReference
    private ActivityApi activityApi;

    @DubboReference
    private UserLikeApi userLikeApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private VisitorsApi visitorsApi;
    @Autowired//根据类型装配
//    @Resource//根据名字装配，RedisTemplate<Object,Object>这是标准类型，若我们写成RedisTemplate<String,Object>，就按照类型找不到，按照名字可以找到
    private RedisTemplate<String,String> redisTemplate;

    public void sendMsg(String phone) {
        //4、通过手机号码查询用户
        User user = userApi.findByMobile(phone);
        //校验用户是否被冻结
        if (user!=null) {
            String value = redisTemplate.opsForValue().get(Constants.USER_FREEZE_KEY + user.getId());
            if (StringUtils.isNotEmpty(value) && value.equals("冻结登录")) {
                Long time = redisTemplate.opsForValue().getOperations().getExpire(Constants.USER_FREEZE_KEY + user.getId());
                Date date = new Date(System.currentTimeMillis() + (time * 1000));
                String ExpireDate = date.toLocaleString();
                //用户已被冻结
                throw new BusinessException(new ErrorResult("0000011", "该用户已被冻结至" + ExpireDate));
            }
        }
        /*//随机生成6位数字
        String code = RandomStringUtils.randomNumeric(6);
        //调用template对象，发送手机短信
        template.sendSms(phone, code);*/
        String code ="123456";
        //将验证码存入到redis
        redisTemplate.opsForValue().set(Constants.SMS_CODE + phone, code, Duration.ofDays(7));
    }

    public Map loginVerification(String phone, String code) {
        //从Redis中获取验证码
        String key = Constants.SMS_CODE + phone;
        boolean isNew=false;
        String checkCode =(String) redisTemplate.opsForValue().get(key);
        //判断验证码是否正确，有效
        if(!code.equalsIgnoreCase(checkCode)|| StringUtils.isEmpty(code)){
            throw new RuntimeException("验证码错误");
        }
        //删除Redis中的验证码
        redisTemplate.delete(key);
        //通过手机号码查询用户
        User user = userApi.findByMobile(phone);
        //不存在就创建用户保存到数据库中
        if (user==null){
            user = new User();
            isNew=true;
            user.setMobile(phone);
            user.setPassword(DigestUtils.md5Hex("123456"));
            Long id =userApi.save(user);
            user.setId(id);
            //注册环信用户
            String hxUser = Constants.HX_USER_PREFIX +user.getId();
            Boolean res = huanXinTemplate.createUser(hxUser, Constants.INIT_PASSWORD);
            if(res){//注册环信成功
                user.setHxUser(hxUser);
                user.setHxPassword(Constants.INIT_PASSWORD);
                Activity activity = new Activity();
                activity.setUserId(user.getId());
                activity.setActivityDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
                activity.setActivityType(LogTypeEnum.REGISTER.getValue());
                activity.setDate(new Date());
                activityApi.save(activity);
                userApi.update(user);//更新user
            }
        }

        //TODO:查询用户最新一次活动记录的时间--此段代码用于更新用户的活跃天数
//        获取最新一次记录
        Activity newActicity =  activityApi.queryBestNewDate(user.getId());
        //获取上一次的登录日期
//        Integer lastActivityDate = Integer.valueOf(newActicity.getActivityDate());
        //今天的登录日期
        String nowDate = new SimpleDateFormat("yyyyMMdd").format(new Date());
        Integer nowActivityDate = Integer.valueOf(nowDate);
        //两个时间相比,如果大于1,将天数重置
        if (newActicity!=null && nowActivityDate-Integer.valueOf(newActicity.getActivityDate())>1){
            user.setActiveDays(1);
            //TODO:2022.6.22二次修改更新数据表
            userApi.update(user);
        }else {
            //不大于1,查询今天是否进行过任意活动
            List<Activity> activities =  activityApi.queryAcivity(user.getId(),nowDate);
            //如果没有记录,说明今天未进行登录,此时将记录天数加一
            if (CollUtil.isEmpty(activities)){
                user.setActiveDays(user.getActiveDays()==null?0:user.getActiveDays()+1);
                //更新数据表
                userApi.update(user);
            }
        }
        //TODO:保存用户最新的活动记录
        //TODO:增加用户登录状态代码:查询今天用户是否有过登录的记录,如果有就更新,没有就保存
        //查询用户今天是否登录过
        Activity logActivity = activityApi.queryActivity(user.getId(), nowDate, LogTypeEnum.LOGIN.getValue());
        if (logActivity==null){
            //添加用户活跃状态
            Activity activity = new Activity();
            activity.setUserId(user.getId());
            activity.setActivityDate(nowDate);
            activity.setActivityType(LogTypeEnum.LOGIN.getValue());
            activity.setDate(new Date());
            activityApi.save(activity);
        }else {
            activityApi.update(logActivity);
        }


        //通过jwt生成token
        Map<Object, Object> hashMap = new HashMap<>();
        hashMap.put("id",user.getId());
        hashMap.put("mobile",user.getMobile());
        String token = JwtUtils.getToken(hashMap);
        //构造返回值
        HashMap<Object, Object> resMap = new HashMap<>();
        resMap.put("token",token);
        resMap.put("isNew",isNew);
        return resMap;
    }

    /*互相喜欢、喜欢、粉丝、谁看过我 - 翻页列表*/
    public PageResult findFriends(Integer type, Integer page, Integer pagesize, String nickname) {
        Long userId = UserHolder.getUserId();
        if (1==type){
//          查我的关注,需要返回关注的人的信息,
            List<UserLike> myLikeList = userLikeApi.queryMyLike(page,pagesize,userId);
            if (CollUtil.isEmpty(myLikeList)){
                return new PageResult();
            }
            //查我关注的人
            List<Long> likeUserIds = CollUtil.getFieldValues(myLikeList, "likeUserId", Long.class);
            //提取出id之后,查看对方是否关注了我,如果关注了,就提取对方的id
            List<FriendsVo> friendsVos = new ArrayList<>();
            for (Long likeUserId : likeUserIds) {
                Boolean like = userLikeApi.queryIfLike(likeUserId,userId);
                if (like){
//                    如果是true说明对方也关注了我,查找对方的详情信息和score,是否喜欢
                    UserInfo userInfo = userInfoApi.findById(likeUserId);
                    if (userInfo!=null){
                        int matchRate = RandomUtil.randomInt(60, 99);
                        FriendsVo friendsVo = FriendsVo.init(userInfo, matchRate, true);
                        friendsVos.add(friendsVo);
                    }
                }
            }
            /*if (nickname!=null){
                UserInfo userInfo = userInfoApi.findByNickname(nickname);
                return  tanhuaService.personalInfo(userInfo.getId());
            }*/
            return new PageResult(page,pagesize, (long) friendsVos.size(),friendsVos);
//          根据对方的id,找到详情信息和score



        }else if (2==type){
//          查我关注
            //          查我的关注,需要返回关注的人的信息,
            List<UserLike> myLikeList = userLikeApi.queryMyLike(page,pagesize,userId);
            if (CollUtil.isEmpty(myLikeList)){
                return new PageResult();
            }
            //查我关注的人
            List<Long> likeUserIds = CollUtil.getFieldValues(myLikeList, "likeUserId", Long.class);
//提取出id之后,查看对方是否关注了我,如果关注了,就提取对方的id
            List<FriendsVo> friendsVos = new ArrayList<>();

            Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(likeUserIds, null);
            for (Long likeUserId : likeUserIds) {
                UserInfo userInfo = userInfoMap.get(likeUserId);
                int matchRate = RandomUtil.randomInt(60, 99);
                FriendsVo friendsVo = FriendsVo.init(userInfo, matchRate, true);
                friendsVos.add(friendsVo);
            }
            return new PageResult(page,pagesize, (long) friendsVos.size(),friendsVos);

        }else if (3==type){
//          查粉丝
//            查关注我的人
            List<UserLike> likeMeList = userLikeApi.querylikeMe(page,pagesize,userId);
            if (CollUtil.isEmpty(likeMeList)){
                return new PageResult();
            }
            List<Long> userIds = CollUtil.getFieldValues(likeMeList, "userId", Long.class);
            List<FriendsVo> friendsVos = new ArrayList<>();
            Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(userIds, null);
            for (Long id : userIds) {
                UserInfo userInfo = userInfoMap.get(id);
                int matchRate = RandomUtil.randomInt(60, 99);
                Boolean like = userLikeApi.queryIfLike(userId,id);
                FriendsVo friendsVo = FriendsVo.init(userInfo, matchRate, like);
                friendsVos.add(friendsVo);
            }
            return new PageResult(page,pagesize, (long) friendsVos.size(),friendsVos);
        }else if (4==type){
//          查谁看过我
            List<Visitors> visitors = visitorsApi.queryVisitors(userId, null);
            if (CollUtil.isEmpty(visitors)){
                return new PageResult();
            }
            List<Long> userIds = CollUtil.getFieldValues(visitors, "visitorUserId", Long.class);
            Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(userIds, null);
            List<FriendsVo> friendsVos = new ArrayList<>();
            for (Long id : userIds) {
                UserInfo userInfo = userInfoMap.get(id);
                int matchRate = RandomUtil.randomInt(60, 99);
                FriendsVo friendsVo = FriendsVo.init(userInfo, matchRate, true);
                friendsVos.add(friendsVo);
            }
            return new PageResult(page,pagesize, (long) friendsVos.size(),friendsVos);
        }
        return null;
    }

    public boolean alreadyLove(Long liekUserId) {
        return userLikeApi.queryIfLike(UserHolder.getUserId(),liekUserId);
    }
}
